package cn.fsd.service.impl;

import cn.fsd.domain.CommodityClass;
import cn.fsd.mapper.CommodityClassMapper;
import cn.fsd.query.delivery.ClassQuery;
import cn.fsd.service.CommodityClassService;
import cn.fsd.util.CacheConstant;
import cn.fsd.util.TreeUtil;
import cn.fsd.vo.ClassItem;
import cn.fsd.vo.ClassTreeNode;
import cn.fsd.vo.ClassTreeRoot;
import cn.fsd.vo.PageBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

@Service
@CacheConfig(cacheNames = CacheConstant.CLASS_CACHE_NAME)
public class CommodityClassServiceImpl implements CommodityClassService {

  @Autowired
  CommodityClassMapper classMapper;

  TreeUtil treeutil = TreeUtil.getInstance();

  @Cacheable(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX
      + "all'", unless = "#result.size() == 0")
  @Override
  public List<ClassTreeNode> getAllClasses() {
    return treeutil.enquireTree(classMapper.getAllClass());
  }

  @Cacheable(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX
      + "first'", unless = "#result.size()==0")
  @Override
  public List<ClassTreeRoot> getFirstClasses() {
    return classMapper.getFirstClasses().parallelStream().map(ClassTreeRoot::new).collect(
        Collectors.toList());
  }

  @Override
  public PageBean<ClassTreeRoot> getClassesByPage(ClassQuery query) {

    PageBean<ClassTreeRoot> pageBean = new PageBean<>();

    PageHelper.startPage(query.getPageNow(), query.getPageSize());

    List<ClassTreeRoot> result = classMapper.getFirstClassesByPage(query);

    PageInfo<ClassTreeRoot> pageInfo = new PageInfo<>(result);

    pageInfo.getList().forEach(item -> {
      item.getChildren().addAll(classMapper.getClassesByParent(item.getClassId()));
    });

    pageBean.setTotalPages(pageInfo.getPages());
    pageBean.setTotalRows(pageInfo.getTotal());
    pageBean.setRowData(pageInfo.getList());

    return pageBean;
  }

  @Cacheable(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX
      + "' + #id", unless = "#result == null")
  @Override
  public ClassTreeRoot getById(String id) {
    return classMapper.selectByPrimaryKey(id);
  }

  @Caching(evict = {@CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "' + #id"), @CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "all'"),
      @CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "first'")})
  @Override
  public void deleteById(String id) {
    ClassTreeRoot entry = classMapper.selectByPrimaryKey(id);
    if (entry != null && entry.getLevel() == 0) {
      classMapper.deleteByParentId(entry.getClassId());
    }
    classMapper.deleteByPrimaryKey(id);
  }

  @Caching(evict = {@CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "all'"),
      @CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "first'")})
  @Override
  public String addClass(ClassItem newClass) {
    String id = UUID.randomUUID().toString();
    newClass.setClassId(id);
    classMapper.insert(newClass);
    return id;
  }

  @Override
  public CommodityClass getByName(String name) {
    return classMapper.getByName(name);
  }

  @Caching(evict = {@CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "all'"),
      @CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "first'"),
      @CacheEvict(key = "'" + CacheConstant.CLASS_CACHE_KEY_PREFIX + "' + #item.classId")})
  @Override
  public void updateClass(ClassItem item) {
    classMapper.updateByPrimaryKey(item);
  }

  @Override
  public CommodityClass getClassById(String classId) {
    return classMapper.selectById(classId);
  }
}
